/*
 * FileName:OPCUtil.java, v1.0 Oct 29, 2017 11:22:55 PM created by TROYJJ
 *
 * @author Xu.YanJun
 * Copyright (c) 2016 iSoftStone 
 * All Rights Reserved.
 * Confidential and for internal user only.
 */
package OPCUtil.task;

import OPCUtil.service.BaseConfiguration;
import org.apache.log4j.Logger;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIVariant;
import org.openscada.opc.lib.da.AutoReconnectController;
import org.openscada.opc.lib.da.Group;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.Server;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

public class OPCTaskServer {

	private Server OPCServer;

	private AutoReconnectController controller;

	private  Logger  log = Logger.getLogger(OPCTaskServer.class);

	private  Map<String,Map<String,Item>> groupItemMap = new HashMap<String,Map<String,Item>>();

	private  Map<String,Item> itemMap = new HashMap<String,Item>();

	private  Map<String,String> valueMap = new HashMap<String,String>();


	//是否启用线程读取
	private boolean flag = false;

	private String taskName = "";

	public OPCTaskServer(String taskName) {
		this.taskName=taskName;
		initServer();
	}

	public OPCTaskServer(String taskName,boolean flag) {
		this.taskName=taskName;
		this.flag=flag;
		initServer();
	}

	private void initServer() {
		if(OPCServer!=null&&controller!=null) {
			return;
		}

		OPCServer = new Server(BaseConfiguration.getCLSIDConnectionInfomation(),
				Executors.newSingleThreadScheduledExecutor());
		try {
			System.out.println("创建OPC连接-------------------------------");
			controller = new AutoReconnectController(OPCServer);
			Thread.sleep(1000);
			controller.connect();
			Thread.sleep(1000);
			System.out.println("链接状态"+OPCServer.toString());
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}




	private Server getOPCServer() {
		if(OPCServer==null) {
			initServer();
		}
		return OPCServer;
	}

	/**
	 * 添加组
	 * @param name
	 * @return
	 */
	public Group addGroup(String name) {
		Group group = null;
		try {
			group = getGroup(name);
			if(group==null) {
				group = getOPCServer().addGroup(name);
			}
			log.info("添加group:"+name+"-------------------------------");
			return group;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获得组
	 * @param name
	 * @return
	 */
	public  Group getGroup(String name) {
		Group group = null;
		try {
			group = getOPCServer().findGroup(name);
			return group;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 添加设备节点
	 * @param groupName
	 * @param itemName
	 * @return
	 */
	public  Item addGroupItem(String groupName,String itemName) {
		return addItem( groupName, itemName,null);
	}

	public  Item addItem(String itemName) {
		return addItem( taskName, itemName,null);
	}

	public  Item addItem(String itemName,Object value) {
		return addItem(taskName,itemName,value);
	}

	/**
	 * 添加设备节点，并发送值
	 */
	public  Item addItem(String groupName,String itemName,Object value) {
		try {
			Group group = getGroup(groupName);
			if(group==null) {
				group = addGroup(groupName);
			}
			Item item = group.addItem(itemName);
			if(value != null) {
				JIVariant jiv = new JIVariant(String.valueOf(value));
				item.write(jiv);
				log.info("向OPC写入值:item="+itemName+",value="+value+"-------------------------------");
			}else {
				Map<String,Item> map = null;
				map = groupItemMap.get(groupName);
				if(map==null) {
					map = new HashMap<String,Item>();
				}
				map.put(itemName, item);
				groupItemMap.put(groupName, map);
				itemMap.put(itemName, item);
			}
			log.info("添加item:"+itemName);
			return item;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 删除一个组及其下的全部节点
	 * @param groupName
	 */
	public  void removeGroupItem(String groupName) {
		try {
			getOPCServer().removeGroup(getGroup(groupName), true);
			groupItemMap.remove(groupName);
			log.info("删除groupItem:"+groupName);
			for(String key : itemMap.keySet()) {
				Item item = itemMap.get(key);
				if(item==null) {
					continue;
				}
				if(groupName.equals(item.getGroup().getName())) {
					itemMap.remove(key);
					valueMap.remove(key);
					log.info("删除item,valueMap中的item:item="+key);
				}
			}
		} catch (JIException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除item
	 * @param itemName
	 */
	public  void removeItem(String itemName) {
		try {
			for(String key : groupItemMap.keySet()) {
				Map<String,Item> map = groupItemMap.get(key);
				if(map==null) {
					continue;
				}
				for(String k : map.keySet()) {
					Item item = map.get(k);
					if(itemName.equals(item.getId())) {
						itemMap.remove(k);
						valueMap.remove(k);
						map.remove(k);
						log.info("删除item,valueMap,group中的item:item="+k);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取item的value
	 * @param itemName
	 * @return
	 * @throws JIException
	 */
	public  String getValue(String itemName) {
		String obj ;
		obj = readValue(itemName);
		return obj;
	}
	/**
	 * 获取group的全面value
	 * @param groupName
	 * @return
	 */
	public  Map<String,String> getGroupValue(String groupName) {
		Map<String,Item> map = groupItemMap.get(groupName);
		Map<String,String> result = new HashMap<String,String>();
		if(map==null) {
			return result;
		}
		for(String key : map.keySet()) {
			Item item = map.get(key);
			String obj = valueMap.get(item.getId());
			if(obj!=null) {
				result.put(item.getId(), obj);
			};
		}
		return result;
	}

	/**
	 * 获取全部value
	 * @return
	 */
	public  Map<String,Object> getAllValue(){
		Map<String,Object> result = new HashMap<String,Object>();
		for(String key : valueMap.keySet()) {
			Object obj = valueMap.get(key);
			if(obj!=null) {
				result.put(key, obj);
			};
		}
		return result;
	}

	/**
	 * 读取全部item的value
	 */
	public  Map<String,String> readAllValue() {
		try {
			for(String key : itemMap.keySet()) {
				Item item = itemMap.get(key);
				if(item==null) {
					continue;
				}
				JIVariant jiv = item.read(true).getValue();
				String value="";
				try{
					value = jiv.getObjectAsUnsigned().getValue().toString();
				}catch(NullPointerException ex){
					value = "";
				}catch (IllegalStateException e){
					if(jiv.getType()>0) {
						value = jiv.getObject().toString();
					}
				}
				valueMap.put(key, value);

				//		System.out.println("读取数据："+item.getId()+",value:"+value);
			}
			return valueMap;
		} catch (JIException e) {
			e.printStackTrace();
		}
		return null;
	}

	private String  readValue(String itemName) {
		try {
			String value="";
			/*value = getValue(itemName);
			if(value!=null) {
				return value;
			}*/
			Item item = addItem(itemName);
			JIVariant jiv = item.read(true).getValue();
			try{
				value = jiv.getObjectAsUnsigned().getValue().toString();
			}catch(NullPointerException ex){
				value = "";
			}catch (IllegalStateException e){
				if(jiv.getType()>0) {
					value = jiv.getObject().toString();
				}
			}
			addItem(taskName,itemName);
			valueMap.put(itemName, value);
			return value;
		}catch (JIException e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean itemIsNull() {
		if(itemMap.size()==0) {
			return true;
		}
		return false;
	}

	public  void disConnect() {
		OPCServer.getScheduler().shutdownNow();
		OPCServer.disconnect();
		OPCServer = null;
		groupItemMap = new HashMap<String,Map<String,Item>>();
		itemMap = new HashMap<String,Item>();
		valueMap = new HashMap<String,String>();
		log.info("opcServer:"+taskName+"关闭------------------------------");
	}


	public String getTaskName() {
		return taskName;
	}

	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

	public static void main(String[] args) throws InterruptedException {
		//	OPCTaskServer.getServer();
		/*OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B154");
		OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B155");
		OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B156");
		OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B157");
		OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B158");
		OPCUtil.addItem("test", "s7:[xiaojian_LiKu_CZ]DB305B159");
		
		
		int i=0;
		while(true) {
			Map<String,Object> map =OPCUtil.getGroupValue("test");
			for(String key:map.keySet()) {
				System.out.println("key:"+key+",value:"+map.get(key));
			}
			i++;
			Thread.sleep(5000);
		}*/
	}

}
